package org.example.springsecuritydemo.config;


import org.example.springsecuritydemo.service.UserService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

import static org.springframework.security.config.Customizer.withDefaults;

/**
 * <p>
 * TODO
 * </p>
 *
 * @author czq
 * @since 2025-07-01
 */
@Configuration
public class SecurityConfig {


    // 配置自定义的 UserDetailsService
    @Bean
    public UserDetailsService userDetailsService() {
        return new UserService();
    }

    // 配置密码编码器
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        System.out.println("securityFilterChain()");
        // csrf 设置
        // csrfCustomizer.ignoringRequestMatchers(*) 表示所有请求地址都不使用 csrf
        http.csrf(csrfCustomizer -> csrfCustomizer.ignoringRequestMatchers("*"))
                // authorize.anyRequest().authenticated() 表示所有的请求都需要进行身份验证。
                .authorizeHttpRequests(authorize -> authorize
                        // 配置登陆失败页面访问不需要鉴权
                        // 如果不配置，不会跳转到登录失败页面
                        // 因为跳转到登录失败，由于未授权，又重定向到登录页面
                        .requestMatchers("/view/login", "/view/fail").permitAll()
                        .anyRequest().authenticated())
                // formLogin() 用于配置表单登录功能
                .formLogin(e -> e.loginProcessingUrl("/login") // 配置处理登陆请求到地址
                        // 自定义登陆页面地址
                        .loginPage("/view/login")
                        // 自定义登陆成功页面
                        .defaultSuccessUrl("/view/success")
                        // 登陆失败页面
                        .failureUrl("/view/fail")
                        .permitAll())
                // httpBasic() 启用 HTTP 基本认证，withDefaults() 表示使用默认的 HTTP 基本认证配置。
                .httpBasic(withDefaults());

        return http.build();
    }
}
